package com.yykj.hospital.server.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.yykj.common.constant.RedisConstant;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.service.RedisService;
import com.yykj.common.vo.PageData;
import com.yykj.common.vo.ResultVO;
import com.yykj.hospital.client.dto.DoctorDTO;
import com.yykj.hospital.client.dto.DoctorInfoDTO;
import com.yykj.hospital.client.dto.HospitalSettingDTO;
import com.yykj.hospital.server.dto.ArticleRollPicListDTO;
import com.yykj.hospital.server.dto.ConsultationCheckDTO;
import com.yykj.hospital.server.dto.DoctorLoginInfo;
import com.yykj.hospital.server.dto.DoctorSignDTO;
import com.yykj.hospital.server.dto.banci.doctor.client.DoctorAppointmentScheduling;
import com.yykj.hospital.server.dto.banci.doctor.client.DoctorOnlineScheduling;
import com.yykj.hospital.server.enums.HospitalNoticeTypeEnum;
import com.yykj.hospital.server.form.DoctorDrugAdviceForm;
import com.yykj.hospital.server.form.DoctorLoginForm;
import com.yykj.hospital.server.form.DoctorSearchForm;
import com.yykj.hospital.server.form.HospitalNoticeListForm;
import com.yykj.hospital.server.form.account.DoctorAccountSearchForm;
import com.yykj.hospital.server.model.entity.*;
import com.yykj.hospital.server.model.entity.account.AccountDoctor;
import com.yykj.hospital.server.model.entity.account.AccountDoctorLog;
import com.yykj.hospital.server.service.*;
import com.yykj.hospital.server.service.account.DoctorAccountService;
import com.yykj.hospital.server.service.banci.DoctorClientBanCiService;
import com.yykj.message.center.client.dto.MessageDTO;
import com.yykj.message.center.client.feign.MessageFeignClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.websocket.server.PathParam;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

@RestController
@RequestMapping("/api/hospital/doctor/client")
@Api(tags = {"医生端APP PC　需要的接口"})
@SuppressWarnings("unchecked")
public class HospitalDoctorClientController {

    @ApiOperation("服务设置 -- 设置价格")
    @PostMapping("/price/setting")
    @ApiOperationSupport(ignoreParameters = {"id", "addTime", "modifyTime"})
    public ResultVO<DoctorOnlinePriceSetting> editPrice(@RequestBody DoctorOnlinePriceSetting setting) {
        return ResultVO.success(service.editDoctorOnlinePriceSetting(setting));
    }

    @ApiOperation("服务设置 -- 查看价格")
    @GetMapping("/price/list")
    public ResultVO<List<DoctorOnlinePriceSetting>> listPrice(@RequestParam(name = "doctorId") String doctorId) {
        return ResultVO.success(service.viewDoctorOnlinePriceSetting(doctorId));
    }

    @ApiOperation("工作台 -- 我的排班 -- 预约挂号")
    @GetMapping("/appointment/scheduling")
    public ResultVO<List<DoctorAppointmentScheduling>> listDoctorScheduling(@RequestParam(name = "doctorId") String doctorId,
                                                                            @RequestParam(name = "startDay") String startDay,
                                                                            @RequestParam(name = "endDay") String endDay) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate sDay = LocalDate.parse(startDay, dateTimeFormatter);
        LocalDate eDay = LocalDate.parse(endDay, dateTimeFormatter);
        return ResultVO.success(doctorClientBanCiService.listDoctorAppointmentScheduling(doctorId, sDay, eDay));
    }

    @ApiOperation("工作台 -- 我的排班 -- 在线问诊")
    @GetMapping("/online/scheduling")
    public ResultVO<List<DoctorOnlineScheduling>> listDoctorOnlineScheduling(@RequestParam(name = "doctorId") String doctorId,
                                                                             @RequestParam(name = "startDay") String startDay,
                                                                             @RequestParam(name = "endDay") String endDay) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate sDay = LocalDate.parse(startDay, dateTimeFormatter);
        LocalDate eDay = LocalDate.parse(endDay, dateTimeFormatter);
        return ResultVO.success(doctorClientBanCiService.listDoctorOnlineScheduling(doctorId, sDay, eDay));
    }

    @PostMapping("/login")
    @ApiOperation("登录 --- 使用账号和密码登录")
    @ApiOperationSupport(ignoreParameters = {"code"})
    public ResultVO<DoctorLoginInfo> login(@RequestBody DoctorLoginForm form) {
        return ResultVO.success(doctorService.login(form));
    }

    @PostMapping("/code/login")
    @ApiOperation("登录 --- 使用手册号和验证码登录")
    @ApiOperationSupport(ignoreParameters = {"password"})
    public ResultVO<DoctorLoginInfo> codeLogin(@RequestBody DoctorLoginForm form) {
        return ResultVO.success(doctorService.loginWithCode(form));
    }

    @PostMapping("/check/code")
    @ApiOperation("登录 --- 获取验证码")
    public ResultVO getMobileCheckCode(String mobile) {
        HospitalDoctor doctor = doctorService.getHospitalDoctorByMobile(mobile);
        if (doctor == null) {
            throw new NormalException(ResultEnums.MOBILE_NOT_REGISTER);
        }
        String s = redisService.get(mobile);
        if(!StringUtils.isEmpty(s)){
            throw new NormalException(ResultEnums.CODE_NOT_EXPIRE);
        }

        ResultVO<MessageDTO> code = messageFeignClient.getCode(mobile);
        if (code.getCode().equals(0)) {
            redisService.set(mobile, code.getData().getCode(), RedisConstant.MESSAGE_EXPIRE);
        } else {
            throw new NormalException(ResultEnums.LOGIN_FAIL, code.getMsg());
        }
        return ResultVO.success();
    }

    @GetMapping("/account/log")
    @ApiOperation("获取账户余额明细")
    @Deprecated
    public ResultVO<PageData<AccountDoctorLog>> listDoctorAccountLog(@RequestParam(name = "doctorId") String doctorId,
                                                                     @RequestParam(name = "startDate", required = false) String startDate,
                                                                     @RequestParam(name = "endDate", required = false) String endDate,
                                                                     @RequestParam(name = "currentPage", required = false) Integer currentPage,
                                                                     @RequestParam(name = "pageSize", required = false) Integer pageSize) {

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = null;
        if (!StringUtils.isEmpty(startDate)) {
            start = LocalDate.parse(startDate, dateTimeFormatter);
        }
        LocalDate end = null;
        if (!StringUtils.isEmpty(endDate)) {
            end = LocalDate.parse(endDate, dateTimeFormatter);
        }

        DoctorAccountSearchForm form = DoctorAccountSearchForm.builder()
                .doctorId(doctorId)
                .startDate(start)
                .endDate(end)
                .currentPage(currentPage)
                .pageSize(pageSize)
                .build();

        return ResultVO.success(doctorAccountService.getDoctorAccountLog(form));
    }

    @GetMapping("/account/balance")
    @ApiOperation("获取账户余额")
    public ResultVO<AccountDoctor> getDoctorAccountBalance(@RequestParam(name = "hospitalId") Integer hospitalId,
                                                           @RequestParam(name = "doctorId") String doctorId) {
        return ResultVO.success(doctorAccountService.getAccountDoctor(hospitalId, doctorId));
    }

    @PostMapping("/reset/password")
    @ApiOperation("通过短信验证码重置密码")
    public ResultVO resetPassword(@RequestBody DoctorLoginForm form) {
        doctorService.resetPassword(form);
        return ResultVO.success();
    }

    @ApiOperation("医生签名设置")
    @PostMapping("/sign/edit")
    public ResultVO editDoctorSign(@RequestBody DoctorSignDTO doctorSignDTO) {
        doctorService.editDoctorSign(doctorSignDTO);
        return ResultVO.success();
    }

    @ApiOperation("获取医生签名")
    @GetMapping("/sign/{doctorId}")
    public ResultVO<DoctorSignDTO> viewDoctorSign(@PathVariable String doctorId) {
        return ResultVO.success(doctorService.viewDoctorSign(doctorId));
    }

    @ApiOperation("医生端 -- 用药医嘱 -- 添加 ")
    @PostMapping("/drug/advice/add")
    @ApiOperationSupport(ignoreParameters = {"id"})
    public ResultVO<DoctorDrugAdvice> addDoctorDrugAdvice(@RequestBody DoctorDrugAdviceForm form){
        return ResultVO.success(drugAdviceService.editDoctorDrugAdvice(form));
    }

    @ApiOperation("医生端 -- 用药医嘱 -- 修改")
    @PutMapping("/drug/advice/edit")
    public ResultVO<DoctorDrugAdvice> editDoctorDrugAdvice(@RequestBody DoctorDrugAdviceForm form){
        return ResultVO.success(drugAdviceService.editDoctorDrugAdvice(form));
    }

    @ApiOperation("医生端 -- 用药医嘱 -- 列表")
    @PutMapping("/drug/advice/list/{doctorId}")
    public ResultVO<List<DoctorDrugAdvice>> listDoctorDrugAdvice(@PathVariable String doctorId){
        return ResultVO.success(drugAdviceService.listDoctorDrugAdvice(doctorId));
    }

    @ApiOperation("医生端 -- 用药医嘱 -- 删除")
    @DeleteMapping("/drug/advice/delete/{id}")
    public ResultVO deleteDoctorDrugAdvice(@PathVariable Integer id){
        drugAdviceService.deleteDoctorDrugAdvice(id);
        return ResultVO.success();
    }

    @ApiOperation("医生端 -- 学术文章 -- 关注")
    @PostMapping("/article/subscribe")
    @ApiOperationSupport(ignoreParameters = {"id"})
    public ResultVO subscribeDoctorArticle(@RequestBody DoctorArticleInterest doctorArticleInterest){
        articleService.subscribeDoctorArticle(doctorArticleInterest);
        return ResultVO.success();
    }

    @ApiOperation("医生端 -- 学术文章 -- 取消关注")
    @ApiOperationSupport(ignoreParameters = {"id"})
    @DeleteMapping("/article/subscribe")
    public ResultVO deSubscribeDoctorArticle(@RequestBody DoctorArticleInterest doctorArticleInterest){
        articleService.deSubscribeDoctorArticle(doctorArticleInterest);
        return ResultVO.success();
    }

    @ApiOperation("添加好友 -- 搜索医生")
    @GetMapping("/search")
    public ResultVO<List<DoctorInfoDTO>> searchDoctor(@RequestParam(name = "mobile",required = false) String mobile,
                                                      @RequestParam(name = "doctorName",required = false) String doctorName,
                                                      @RequestParam(name = "currentPage",defaultValue = "1") Integer currentPage,
                                                      @RequestParam(name = "pageSize",defaultValue = "10") Integer pageSize){
        DoctorSearchForm searchForm = DoctorSearchForm.builder()
                .mobile(mobile)
                .doctorName(doctorName)
                .currentPage(currentPage)
                .pageSize(pageSize)
                .build();
        return ResultVO.success(doctorService.doctorSearchDoctor(searchForm));
    }

    @ApiOperation("会诊是否需要后台审核")
    @GetMapping("/consultation/check/{hospitalId}")
    public ResultVO<ConsultationCheckDTO> consultationCheck(@PathVariable Integer hospitalId){
        HospitalSettingDTO hospitalSetting = hospitalService.getHospitalSetting(hospitalId);
        ConsultationCheckDTO checkDTO = new ConsultationCheckDTO();
        BeanUtils.copyProperties(hospitalSetting,checkDTO);
        return ResultVO.success(checkDTO);
    }

    @ApiOperation("医院 -- 医院公告")
    @GetMapping("/hospital/notice")
    public ResultVO<HospitalNotice> listHospitalNotice(@RequestParam(name = "hospitalId") Integer hospitalId,
                                                       @RequestParam(name = "currentPage", defaultValue = "1") Integer currentPage,
                                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {

        HospitalNoticeListForm form = HospitalNoticeListForm.builder()
                .hospitalId(hospitalId)
                .currentPage(currentPage)
                .type(HospitalNoticeTypeEnum.doctor)
                .pageSize(pageSize)
                .status(true)
                .build();

        return ResultVO.success(noticeService.listHospitalNotice(form));
    }


    @ApiOperation("学术滚动图片列表")
    @GetMapping("/article/roll/pic/{hospitalId}")
    public ResultVO<List<ArticleRollPicListDTO>> articleRollPicList(@PathVariable Integer hospitalId){
        return ResultVO.success(articleService.articleRollPicList(hospitalId));
    }

    private HospitalService hospitalService;

    private HospitalNoticeService noticeService;


    private DrugAdviceService drugAdviceService;

    private HospitalSettingService service;

    private DoctorClientBanCiService doctorClientBanCiService;

    private HospitalDoctorService doctorService;

    private MessageFeignClient messageFeignClient;

    private RedisService redisService;

    private DoctorAccountService doctorAccountService;

    private ArticleService articleService;

    @Autowired
    public void setService(HospitalSettingService service) {
        this.service = service;
    }

    @Autowired
    public void setDoctorClientBanCiService(DoctorClientBanCiService doctorClientBanCiService) {
        this.doctorClientBanCiService = doctorClientBanCiService;
    }

    @Autowired
    public void setDoctorService(HospitalDoctorService doctorService) {
        this.doctorService = doctorService;
    }

    @Autowired
    public void setMessageFeignClient(MessageFeignClient messageFeignClient) {
        this.messageFeignClient = messageFeignClient;
    }

    @Autowired
    public void setRedisService(RedisService redisService) {
        this.redisService = redisService;
    }

    @Autowired
    public void setDoctorAccountService(DoctorAccountService doctorAccountService) {
        this.doctorAccountService = doctorAccountService;
    }
    @Autowired
    public void setDrugAdviceService(DrugAdviceService drugAdviceService) {
        this.drugAdviceService = drugAdviceService;
    }
    @Autowired
    public void setArticleService(ArticleService articleService) {
        this.articleService = articleService;
    }

    @Autowired
    public void setHospitalService(HospitalService hospitalService) {
        this.hospitalService = hospitalService;
    }

    @Autowired
    public void setNoticeService(HospitalNoticeService noticeService) {
        this.noticeService = noticeService;
    }
}
